#include "CombatScene.h"
#include "HpBar.h"
#include "XpBar.h"

using namespace std;

CombatScene::CombatScene(string _sceneID)
	: SDLScene(_sceneID), m_CurrentPhase(COMBAT_INITIATION), m_IsInitialized(false), m_CurrentAnim(0)
{
	SDLEngine::GetInstance()->AddScene("Combat", this);
	InitInterface();
	InitPlayer();
	InitEnemy();
	
	m_MainMenu.SetVisible(false);
	m_AttackMenu.SetVisible(false);
	m_AttackInfoMenu.SetVisible(false);
	m_ActionMenu.SetVisible(false);
	m_Cursor->SetVisible(false);

	SetChoiceMatrix(false);
}

CombatScene::~CombatScene()
{

}

void CombatScene::InitInterface()
{
	m_Bkg = new SDLSprite(0,0,0,0,240,160, "Image/BattleBackground.png", this);
	m_BkgText = new SDLText("", "arial.ttf", 9, this);
	m_BkgText->SetPosition(MAIN_TEXT_POSITION_X, MAIN_TEXT_POSITION_Y);
	m_BkgText->SetTextColor(0, 0, 0);

	m_MainMenu.SetBackground(new SDLSprite(ATTACK_MENU_POSITION_X, ATTACK_MENU_POSITION_Y, 0, 464, 240, 48, "Image/Utilities.png", this));
	SDLText* newText = new SDLText("Main Text", "arial.ttf", 9, this);
	newText->SetPosition(MAIN_TEXT_POSITION_X, MAIN_TEXT_POSITION_Y);
	newText->SetTextColor(0, 0, 0);
	m_MainMenu.AddText(newText);
	
	m_AttackMenu.SetBackground(new SDLSprite(ATTACK_MENU_POSITION_X, ATTACK_MENU_POSITION_Y, 0, 464, 240, 48, "Image/Utilities.png", this));

	newText = new SDLText("", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_TEXT_POSITION_X, ATTACK_TEXT_POSITION_Y);
	newText->SetTextColor(0,0,0);

	m_AttackMenu.AddText(newText);

	newText = new SDLText("", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_TEXT_POSITION_X + 70, ATTACK_TEXT_POSITION_Y);
	newText->SetTextColor(0,0,0);

	m_AttackMenu.AddText(newText);
	
	newText = new SDLText("", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_TEXT_POSITION_X, ATTACK_TEXT_POSITION_Y + 18);
	newText->SetTextColor(0,0,0);

	m_AttackMenu.AddText(newText);

	newText = new SDLText("", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_TEXT_POSITION_X + 70, ATTACK_TEXT_POSITION_Y + 18);
	newText->SetTextColor(0,0,0);

	m_AttackMenu.AddText(newText);
	m_AttackInfoMenu.SetBackground(new SDLSprite(ATTACK_INFO_MENU_X, ATTACK_INFO_MENU_Y, 0, 320, 80, 48, "Image/Utilities.png", this));
	
	newText = new SDLText("PP", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_INFO_MENU_X + 8, ATTACK_INFO_MENU_Y + 6);
	newText->SetTextColor(0,0,0);

	m_AttackInfoMenu.AddText(newText);

	newText = new SDLText("TYPE", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_INFO_MENU_X + 8, ATTACK_INFO_MENU_Y + 17);
	newText->SetTextColor(0,0,0);

	m_AttackInfoMenu.AddText(newText);

	newText = new SDLText("", "arial.ttf", 10, this);
	newText->SetPosition(ATTACK_INFO_MENU_X + 8, ATTACK_INFO_MENU_Y + 28);
	newText->SetTextColor(0,0,0);

	m_AttackInfoMenu.AddText(newText);

	m_ActionMenu.SetBackground(new SDLSprite(ACTION_MENU_POSITION_X, ACTION_MENU_POSITION_Y, 0, 416, 120, 48, "Image/Utilities.png", this));
	m_Cursor = new SDLSprite(0, 0, 0, 27, 5, 9, "Image/Utilities.png", this);
}

void CombatScene::InitPlayer()
{
	m_CurrentPokemon = m_Player.GetFirstPokemon();
	m_PlayerSprite = new Animations(*m_CurrentPokemon, PLAYER_POSITION_X, PLAYER_POSITION_Y, true, this);

	m_PlayerHpBar = new HpBar(PLAYER_LIFEBAR_POSITION_X, PLAYER_LIFEBAR_POSITION_Y, 0, 37, 48, 3, "Image/Utilities.png", m_CurrentPokemon, this);
	m_PlayerXpBar = new XpBar(XPBAR_POSITION_X, XPBAR_POSITION_Y, 0, 46, 64, 2, "Image/Utilities.png", m_CurrentPokemon, this);

	m_PlayerName = new SDLText(m_CurrentPokemon->GetName(), "arial.ttf", 10, this);
	m_PlayerName->SetPosition(149, 77);
	m_PlayerName->SetTextColor(0,0,0);

	std::stringstream ss;
	ss << m_CurrentPokemon->GetCurrentHP() << " / " << m_CurrentPokemon->GetMaxHP();

	m_PlayerHP = new SDLText(ss.str(), "arial.ttf", 9, this);
	m_PlayerHP->SetPosition(195, 96);
	m_PlayerHP->SetTextColor(0,0,0);

	ss.str("");
	ss << m_CurrentPokemon->GetLevel();

	m_PlayerLevel = new SDLText(ss.str(), "arial.ttf", 9, this);
	m_PlayerLevel->SetPosition(223, 79);
	m_PlayerLevel->SetTextColor(0,0,0);

	m_PlayerAttack = new Animations(PokemonLoader::GetInstance()->GetAnimationData(SCYTHE), PLAYER_ATTACK_POSITION_X, PLAYER_ATTACK_POSITION_Y, this);
}

void CombatScene::InitEnemy()
{
	int randomPokemon;
	vector<int> pokemonPool;

	if(m_CurrentPokemon->GetLevel() > HARD_GROUP_LEVEL)
	{
		randomPokemon = rand() % HARD_GROUP_COUNT;
		pokemonPool = PokemonLoader::GetInstance()->GetGroup(HARD);
	}
	else if(m_CurrentPokemon->GetLevel() > MEDIUM_GROUP_LEVEL)
	{
		randomPokemon = rand() % MEDIUM_GROUP_COUNT;
		pokemonPool = PokemonLoader::GetInstance()->GetGroup(MEDIUM);
	}
	else
	{
		randomPokemon = rand() % EASY_GROUP_COUNT;
		pokemonPool = PokemonLoader::GetInstance()->GetGroup(EASY);
	}
	
	int randomLevel = rand() % 4 + (m_CurrentPokemon->GetLevel() - 2);
	m_Enemy = Pokemon(PokemonLoader::GetInstance()->GetPokemonData(pokemonPool[randomPokemon]), randomLevel);
	m_Enemy.SetCurrentXP(randomLevel * randomLevel * randomLevel);
	
	m_EnemySprite = new Animations(m_Enemy, ENEMY_POSITION_X, ENEMY_POSITION_Y, this);
	m_EnemyHpBar = new HpBar(ENEMY_LIFEBAR_POSITION_X, ENEMY_LIFEBAR_POSITION_Y, 0, 37, 48, 3, "Image/Utilities.png", &m_Enemy, this);

	m_EnemyName = new SDLText(m_Enemy.GetName(), "arial.ttf", 10, this);
	m_EnemyName->SetPosition(9, 6);
	m_EnemyName->SetTextColor(0,0,0);

	stringstream ss;
	ss << m_Enemy.GetLevel();

	m_EnemyLevel = new SDLText(ss.str(), "arial.ttf", 9, this);
	m_EnemyLevel->SetPosition(83, 7);
	m_EnemyLevel->SetTextColor(0,0,0);

	m_EnemyAttack = new Animations(PokemonLoader::GetInstance()->GetAnimationData(SCYTHE), ENEMY_ATTACK_POSITION_X, ENEMY_ATTACK_POSITION_Y, this);
	m_PokeballSprite = new SDLAnimation(4, 4, ENEMY_ATTACK_POSITION_X, ENEMY_ATTACK_POSITION_Y, 0, 128, 32, 32, false, true, "Image/Utilities.png", this);
	m_PokeballSprite->SetVisible(false);
}

void CombatScene::GetNewEnemy()
{
	int randomPokemon;
	vector<int> pokemonPool;

	if(m_CurrentPokemon->GetLevel() > HARD_GROUP_LEVEL)
	{
		randomPokemon = rand() % HARD_GROUP_COUNT;
		pokemonPool = PokemonLoader::GetInstance()->GetGroup(HARD);
	}
	else if(m_CurrentPokemon->GetLevel() > MEDIUM_GROUP_LEVEL)
	{
		randomPokemon = rand() % MEDIUM_GROUP_COUNT;
		pokemonPool = PokemonLoader::GetInstance()->GetGroup(MEDIUM);
	}
	else
	{
		randomPokemon = rand() % EASY_GROUP_COUNT;
		pokemonPool = PokemonLoader::GetInstance()->GetGroup(EASY);
	}
	
	int randomLevel = rand() % 4 + (m_CurrentPokemon->GetLevel() - 2);
	m_Enemy = Pokemon(PokemonLoader::GetInstance()->GetPokemonData(pokemonPool[randomPokemon]), randomLevel);
	//m_Enemy = Pokemon(PokemonLoader::GetInstance()->GetPokemonData(13), randomLevel);
	m_Enemy.SetCurrentXP(randomLevel * randomLevel * randomLevel);
	
	m_EnemySprite->SetPokemon(m_Enemy.GetNumber(), false);
	m_EnemyHpBar->SetPokemon(&m_Enemy);
	*m_EnemyName =m_Enemy.GetName();

	stringstream ss;
	ss << m_Enemy.GetLevel();
	*m_EnemyLevel = ss.str();
}

void CombatScene::Update()
{
	SDLScene::Update();

	if(m_MainMenu.IsVisible())
		*(m_MainMenu.GetTexts()[0]) = m_MainOutput.str();

	switch(m_CurrentPhase)
	{
	case COMBAT_INITIATION:
		CombatInitiation();
		break;
	case SELECT_ACTION:
		SelectAction();
		break;
	case SELECT_ATTACK:
		SelectAttack();
		break;
	case PLAYER_STANDBY:
		PlayerStandBy();
		break;
	case PLAYER_ATTACK:
		PlayerAttack();
		break;
	case ENEMY_STANDBY:
		EnemyStandBy();
		break;
	case ENEMY_ATTACK:
		EnemyAttack();
		break;
	case PLAYER_ATTACK_RECAP:
		PlayerAttackRecap();
		break;
	case ENEMY_ATTACK_RECAP:
		EnemyAttackRecap();
		break;
	case SWAP_POKEMON:
		break;
	case CATCH_POKEMON:
		Catch();
		break;
	case RUN:
		Run();
		break;
	case FIGHT_SUMMARY:
		FightSummary();
		break;
	case FORGET_ATTACK:
		ForgetAttack();
		break;
	case END_TURN:
		EndTurn();
		break;
	}
}

void CombatScene::UpdateUI()
{
	stringstream ss;
	ss << m_CurrentPokemon->GetCurrentHP() << " / " << m_CurrentPokemon->GetMaxHP();
	*m_PlayerHP = ss.str();
	*m_PlayerName = m_CurrentPokemon->GetName();

	ss.str("");
	ss << m_CurrentPokemon->GetLevel();
	*m_PlayerLevel = ss.str();

	*m_EnemyName = m_Enemy.GetName();

	ss.str("");
	ss << m_Enemy.GetLevel();
	*m_EnemyLevel = ss.str();
}

void CombatScene::CombatInitiation()
{
	if(!m_IsInitialized)
	{
		GetNewEnemy();
		m_Player.InitAllPokemons();
		UpdateUI();

		m_MainMenu.SetVisible(false);
		m_AttackMenu.SetVisible(false);
		m_AttackInfoMenu.SetVisible(false);

		m_BkgText->SetVisible(true);
		m_EnemyName->SetVisible(false);
		m_EnemyLevel->SetVisible(false);
		m_EnemyHpBar->SetVisible(false);
		m_EnemySprite->SetVisible(false);
		m_EnemyAttack->SetVisible(false);
		m_PlayerAttack->SetVisible(false);

		stringstream ss;
		ss << "A wild " << m_Enemy.GetName() << " appears!";
		*m_BkgText = ss.str();

		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		*m_BkgText = "";
		m_EnemyName->SetVisible(true);
		m_EnemyLevel->SetVisible(true);
		m_EnemyHpBar->SetVisible(true);
		m_EnemySprite->SetVisible(true);

		m_CurrentPhase = SELECT_ACTION;
		m_IsInitialized = false;
	}
}

void CombatScene::SelectAction()
{
	if(!m_IsInitialized)
	{
		UpdateUI();
		m_CurrentPokemon->SetHasAttacked(false);
		m_Enemy.SetHasAttacked(false);

		m_ChoiceMatrix[0][0] = true;
		m_MainMenu.SetVisible(true);
		m_ActionMenu.SetVisible(true);
		m_Cursor->SetVisible(true);
		m_Cursor->SetPosition(ACTION_MENU_POSITION_X + 8, ACTION_MENU_POSITION_Y + 12);

		m_MainOutput << "What will " << m_CurrentPokemon->GetName() << " do?";

		m_IsInitialized = true;
	}

	if(m_CurrentPokemon->IsWaiting())
	{
		m_MainOutput.str("");
		m_ActionMenu.SetVisible(false);
		m_Cursor->SetVisible(false);
		SetChoiceMatrix(false);

		if(m_CurrentPokemon->GetNextAttack() != -1)
		{
			m_AttackIndex = m_CurrentPokemon->GetNextAttack();

			if(m_CurrentPokemon->GetSpeed() >= m_Enemy.GetSpeed())
				m_CurrentPhase = PLAYER_STANDBY;
			else
				m_CurrentPhase = ENEMY_STANDBY;
		}
		else
		{
			m_MainOutput << m_CurrentPokemon->GetName() << " must recharge" << endl;
			m_CurrentPokemon->SetHasAttacked(true);
			m_CurrentPhase = ENEMY_STANDBY;
		}

		m_CurrentPokemon->SetWaiting(false);
	}
	else
	{
		CheckCursorMovement(57, 17);

		if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
		{
			if(m_ChoiceMatrix[0][0])
				m_CurrentPhase = SELECT_ATTACK;
			else if(m_ChoiceMatrix[0][1])
				m_CurrentPhase = CATCH_POKEMON;
			//else if(m_ChoiceMatrix[1][0])
				//m_CurrentPhase = SWAP_POKEMON;
			else if(m_ChoiceMatrix[1][1])
				m_CurrentPhase = RUN;
		
			SetChoiceMatrix(false);
			m_MainOutput.str("");
			m_Cursor->SetVisible(false);
			m_ActionMenu.SetVisible(false);
			m_IsInitialized = false;
		}
	}
}

void CombatScene::SelectAttack()
{
	if(!m_IsInitialized)
	{
		UpdateUI();
		vector<SDLText*>::iterator iter;

		for(iter = m_AttackMenu.GetTexts().begin(); iter != m_AttackMenu.GetTexts().end(); iter++)
		{
			**iter = "";
		}
		
		m_AttackMenu.SetVisible(true);
		m_AttackInfoMenu.SetVisible(true);
		DisplayPokemonAttacks();
		m_Cursor->SetVisible(true);
		m_Cursor->SetPosition(ATTACK_MENU_POSITION_X + 7, ATTACK_MENU_POSITION_Y + 8);
		m_ChoiceMatrix[0][0] = true;

		m_IsInitialized = true;
	}
	else
	{
		CheckCursorMovementAttack(70, 18);
		DisplayAttackInfo();

		if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
		{
			if(m_ChoiceMatrix[0][0])
				m_AttackIndex = 0;
			else if(m_ChoiceMatrix[0][1])
				m_AttackIndex = 1;
			else if(m_ChoiceMatrix[1][0])
				m_AttackIndex = 2;
			else
				m_AttackIndex = 3;

			if(m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().name == "Quick Attack" || m_CurrentPokemon->GetSpeed() >= m_Enemy.GetSpeed())
				m_CurrentPhase = PLAYER_STANDBY;
			else
				m_CurrentPhase = ENEMY_STANDBY;
			
			SetChoiceMatrix(false);
			m_MainOutput.str("");
			m_Cursor->SetVisible(false);
			m_AttackMenu.SetVisible(false);
			m_AttackInfoMenu.SetVisible(false);
			SetChoiceMatrix(false);

			m_IsInitialized = false;
		}
		else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_BACKSPACE))
		{
			m_IsInitialized = false;
			m_AttackMenu.SetVisible(false);
			m_AttackInfoMenu.SetVisible(false);
			SetChoiceMatrix(false);
			m_CurrentPhase = SELECT_ACTION;
		}
	}
}

void CombatScene::PlayerStandBy()
{
	if(!m_IsInitialized)
	{
		UpdateUI();
		m_MainOutput.str("");
		m_Proceed = m_CurrentPokemon->CanAttack(m_Outputs);

		if(!m_Outputs.empty())
		{
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}

		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN) || m_MainOutput.str() == "")
	{
		if(!m_Outputs.empty())
		{
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}
		else 
		{
			m_CurrentPokemon->SetHasAttacked(true);
			m_IsInitialized = false;

			if(m_Proceed)
				m_CurrentPhase = PLAYER_ATTACK;
			else if(!m_Enemy.HasAttacked())
				m_CurrentPhase = ENEMY_STANDBY;
			else
				m_CurrentPhase = END_TURN;
		}
	}
}

void CombatScene::EnemyStandBy()
{
	if(!m_IsInitialized)
	{
		UpdateUI();
		m_MainOutput.str("");
		m_Proceed = m_Enemy.CanAttack(m_Outputs);

		if(!m_Outputs.empty())
		{
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}

		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN) || m_MainOutput.str() == "")
	{
		m_MainOutput.str("");
		if(!m_Outputs.empty())
		{
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}
		else if(m_Enemy.IsWaiting())
		{
			m_Enemy.SetHasAttacked(true);
			m_CurrentPokemon->SetWaiting(false);
			m_IsInitialized = false;

			if(m_Enemy.GetNextAttack() != -1 && m_Proceed)
			{
				m_AttackIndex = m_Enemy.GetNextAttack();
				m_CurrentPhase = ENEMY_ATTACK;
			}
			else if(m_Enemy.GetNextAttack() == -1 && m_Proceed)
			{
				m_MainOutput << m_Enemy.GetName() << " must recharge";

				if(m_CurrentPokemon->HasAttacked())
					m_CurrentPhase = END_TURN;
				else
					m_CurrentPhase = PLAYER_STANDBY;
			}
			else if(!m_CurrentPokemon->HasAttacked())
				m_CurrentPhase = PLAYER_STANDBY;
			else
				m_CurrentPhase = END_TURN;
		}
		else
		{
			m_Enemy.SetHasAttacked(true);
			m_IsInitialized = false;

			if(m_Proceed)
				m_CurrentPhase = ENEMY_ATTACK;
			else if(!m_CurrentPokemon->HasAttacked())
				m_CurrentPhase = PLAYER_STANDBY;
			else
				m_CurrentPhase = END_TURN;
		}
	}
}

void CombatScene::PlayerAttack()
{
	if(!m_IsInitialized)
	{
		UpdateUI();
		m_MainOutput.str("");
		m_MainOutput << m_CurrentPokemon->GetName() << " uses " << m_CurrentPokemon->GetAttackAt(m_AttackIndex);

		m_IsInitialized = true;
	}

	if(m_CurrentAnim == 0 && SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		m_MainOutput.str("");
		if(m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().targetOther)
		{
			m_EnemyAttack->SetVisible(true);
			m_EnemyAttack->SetAttack(PokemonLoader::GetInstance()->GetAnimationData(m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().animation));

			if(m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().animation == THUNDER_STRIKE || m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().animation == TORNADO)
			{
				m_EnemyAttack->SetPosition(ENEMY_ATTACK_POSITION_X, ENEMY_ATTACK_POSITION_Y - 32);
			}
			m_CurrentAnim = m_EnemyAttack;
		}
		else
		{
			m_PlayerAttack->SetVisible(true);
			m_PlayerAttack->SetAttack(PokemonLoader::GetInstance()->GetAnimationData(m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().animation));

			if(m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().animation == THUNDER_STRIKE || m_CurrentPokemon->GetAttackAt(m_AttackIndex).GetAttackData().animation == TORNADO)
			{
				m_PlayerAttack->SetPosition(PLAYER_ATTACK_POSITION_X, PLAYER_ATTACK_POSITION_Y - 32);
			}
			m_CurrentAnim = m_PlayerAttack;
		}

	}

	if(m_CurrentAnim != 0 && !m_CurrentAnim->IsVisible())
	{
		m_PlayerAttack->SetPosition(PLAYER_ATTACK_POSITION_X, PLAYER_ATTACK_POSITION_Y);
		m_EnemyAttack->SetPosition(ENEMY_ATTACK_POSITION_X, ENEMY_ATTACK_POSITION_Y);

		m_CurrentAnim->SetVisible(false);
		m_CurrentAnim = 0;

		m_CurrentPhase = PLAYER_ATTACK_RECAP;
		m_IsInitialized = false;
	}
}

void CombatScene::EnemyAttack()
{
	if(!m_IsInitialized)
	{
		UpdateUI();
		m_MainOutput.str("");
		
		if(m_Enemy.GetNextAttack() != -1)
			m_EnemyAttackIndex = m_Enemy.GetNextAttack();
		else
			m_EnemyAttackIndex = rand() % m_Enemy.GetAttacks().size();

		m_MainOutput << m_Enemy.GetName() << " uses " << m_Enemy.GetAttackAt(m_EnemyAttackIndex);

		m_IsInitialized = true;
	}

	if(m_CurrentAnim == 0 && SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		m_MainOutput.str("");
		if(m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().targetOther)
		{
			m_PlayerAttack->SetVisible(true);
			m_PlayerAttack->SetAttack(PokemonLoader::GetInstance()->GetAnimationData(m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().animation));

			if(m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().animation == THUNDER_STRIKE || m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().animation == TORNADO)
			{
				m_PlayerAttack->SetPosition(PLAYER_ATTACK_POSITION_X, PLAYER_ATTACK_POSITION_Y - 32);
			}
			m_CurrentAnim = m_PlayerAttack;
		}
		else
		{
			m_EnemyAttack->SetVisible(true);
			m_EnemyAttack->SetAttack(PokemonLoader::GetInstance()->GetAnimationData(m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().animation));

			if(m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().animation == THUNDER_STRIKE || m_Enemy.GetAttackAt(m_EnemyAttackIndex).GetAttackData().animation == TORNADO)
			{
				m_EnemyAttack->SetPosition(ENEMY_ATTACK_POSITION_X, ENEMY_ATTACK_POSITION_Y - 32);
			}
			m_CurrentAnim = m_EnemyAttack;
		}

	}

	if(m_CurrentAnim != 0 && !m_CurrentAnim->IsVisible())
	{
		m_EnemyAttack->SetPosition(ENEMY_ATTACK_POSITION_X, ENEMY_ATTACK_POSITION_Y);
		m_PlayerAttack->SetPosition(PLAYER_ATTACK_POSITION_X, PLAYER_ATTACK_POSITION_Y);

		m_CurrentAnim->SetVisible(false);
		m_CurrentAnim = 0;

		m_CurrentPhase = ENEMY_ATTACK_RECAP;
		m_IsInitialized = false;
	}
}

void CombatScene::PlayerAttackRecap()
{
	if(!m_IsInitialized)
	{
		m_MainOutput.str("");

		m_Outputs = m_CurrentPokemon->Attack(m_CurrentPokemon->GetAttackAt(m_AttackIndex), m_Enemy);
		UpdateUI();
		
		if(m_Outputs.empty())
		{
			stringstream ss;
			ss << m_CurrentPokemon->GetName() << " missed";
			m_Outputs.push(ss.str());
		}

		m_MainOutput << m_Outputs.front();
		m_Outputs.pop();
		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		if(!m_Outputs.empty())
		{
			m_MainOutput.str("");
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}
		else
		{
			m_MainOutput.str("");
			m_IsInitialized = false;

			if(m_Enemy.IsAffectedBy(FAINT))
				m_CurrentPhase = FIGHT_SUMMARY;
			else if(!m_Enemy.HasAttacked())
				m_CurrentPhase = ENEMY_STANDBY;
			else
				m_CurrentPhase = END_TURN;
		}
	}
}

void CombatScene::EnemyAttackRecap()
{
	if(!m_IsInitialized)
	{
		m_MainOutput.str("");

		m_Outputs = m_Enemy.Attack(m_Enemy.GetAttackAt(m_EnemyAttackIndex), *m_CurrentPokemon);
		UpdateUI();

		if(m_Outputs.empty())
		{
			stringstream ss;
			ss << m_Enemy.GetName() << " missed";
			m_Outputs.push(ss.str());
		}

		m_MainOutput << m_Outputs.front();
		m_Outputs.pop();
		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		if(!m_Outputs.empty())
		{
			m_MainOutput.str("");
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}
		else
		{
			m_MainOutput.str("");
			m_IsInitialized = false;

			if(m_CurrentPokemon->IsAffectedBy(FAINT))
				m_CurrentPhase = COMBAT_INITIATION;
			else if(!m_CurrentPokemon->HasAttacked())
				m_CurrentPhase = PLAYER_STANDBY;
			else
				m_CurrentPhase = END_TURN;
		}
	}
}

void CombatScene::FightSummary()
{
	if(!m_IsInitialized)
	{
		m_EnemySprite->SetVisible(false);

		m_MainOutput.str("");
		m_Outputs = m_CurrentPokemon->FightWon(m_Enemy);
		m_MainOutput << m_Outputs.front();
		m_Outputs.pop();

		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		if(!m_Outputs.empty())
		{
			m_MainOutput.str("");
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}
		else
		{
			m_IsInitialized = false;
			m_MainOutput.str("");
			m_MainMenu.SetVisible(false);

			if(m_CurrentPokemon->GetAttacks().size() > 4)
				m_CurrentPhase = FORGET_ATTACK;
			else
				m_CurrentPhase = COMBAT_INITIATION;

			m_PlayerSprite->SetPokemon(m_CurrentPokemon->GetNumber(), true);
			UpdateUI();
		}
	}
}

void CombatScene::EndTurn()
{
	if(!m_IsInitialized)
	{
		m_MainOutput.str("");
		m_Outputs = m_Enemy.EndTurnStatus();
		
		queue<string> temp = m_CurrentPokemon->EndTurnStatus();

		while(!temp.empty())
		{
			m_Outputs.push(temp.front());
			temp.pop();
		}

		if(!m_Outputs.empty())
		{
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}

		UpdateUI();
		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN) || m_MainOutput.str() == "")
	{
		if(!m_Outputs.empty())
		{
			m_MainOutput.str("");
			m_MainOutput << m_Outputs.front();
			m_Outputs.pop();
		}
		else
		{
			m_MainOutput.str("");
			m_IsInitialized = false;
			
			if(m_Enemy.IsDead())
				m_CurrentPhase = FIGHT_SUMMARY;
			else if(m_CurrentPokemon->IsDead())
				m_CurrentPhase = COMBAT_INITIATION;
			else
				m_CurrentPhase = SELECT_ACTION;
		}
	}
}

void CombatScene::Run()
{
	if(!m_IsInitialized)
	{
		m_MainOutput.str("");

		int escape = (m_CurrentPokemon->GetSpeed() * 32)/(m_Enemy.GetSpeed() / 4) + (30 * m_EscapeCount);
		m_EscapeCount++;

		if(escape > 255)
			m_Success =  true;
		else
		{
			int randNumber = rand() % 256;
			m_Success =  randNumber <= escape ? true : false;
		}

		if(m_Success)
			m_MainOutput << "You successfully escaped";
		else
		{
			stringstream ss;
			ss << "You couldn't outrun " << m_Enemy.GetName();
			m_MainOutput << ss.str();
		}

		m_IsInitialized = true;
	}

	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		m_MainOutput.str("");
		m_IsInitialized = false;
		m_CurrentPokemon->SetHasAttacked(true);

		if(m_Success)
		{
			m_CurrentPhase = COMBAT_INITIATION;
			m_EscapeCount = 0;
		}
		else
			m_CurrentPhase = ENEMY_STANDBY;
	}
}

void CombatScene::ForgetAttack()
{
	if(!m_IsInitialized)
	{
		m_MainOutput.str("");
		m_MainMenu.SetVisible(true);
		m_MainOutput << "Which attack do you want to forget";
		m_IsInitialized = true;
	}
	else
	{
		if(!m_AttackMenu.IsVisible() && SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
		{
			m_MainMenu.SetVisible(false);
			m_MainOutput.str("");
			vector<SDLText*>::iterator iter;

			for(iter = m_AttackMenu.GetTexts().begin(); iter != m_AttackMenu.GetTexts().end(); iter++)
			{
				**iter = "";
			}
		
			m_AttackMenu.SetVisible(true);
			m_AttackInfoMenu.SetVisible(true);
			DisplayPokemonAttacks();
			m_Cursor->SetVisible(true);
			m_Cursor->SetPosition(ATTACK_MENU_POSITION_X + 7, ATTACK_MENU_POSITION_Y + 8);
			m_ChoiceMatrix[0][0] = true;

			m_IsInitialized = true;
		}
		else if(m_AttackMenu.IsVisible())
		{
			CheckCursorMovement(70, 18);
			DisplayAttackInfo();

			if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
			{
				if(m_ChoiceMatrix[0][0])
					m_CurrentPokemon->ForgetAttack(0);
				else if(m_ChoiceMatrix[0][1])
					m_CurrentPokemon->ForgetAttack(1);
				else if(m_ChoiceMatrix[1][0])
					m_CurrentPokemon->ForgetAttack(2);
				else
					m_CurrentPokemon->ForgetAttack(3);
				
				m_AttackMenu.SetVisible(false);
				m_AttackInfoMenu.SetVisible(false);
				m_Cursor->SetVisible(false);
				m_CurrentPhase = COMBAT_INITIATION;
				m_IsInitialized = false;
			}
			else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_BACKSPACE))
			{
				m_CurrentPokemon->ForgetAttack(4);

				m_AttackMenu.SetVisible(false);
				m_AttackInfoMenu.SetVisible(false);
				m_CurrentPhase = COMBAT_INITIATION;
				m_IsInitialized = false;
			}
		}
	}
}

void CombatScene::Catch()
{
	if(!m_IsInitialized)
	{
		m_MainOutput.str("");
		m_IsThrown = false;
		m_Caught = false;
		m_Success = false;
		m_Again = true;

		stringstream ss;
		ss << "You throw a pokeball at " << m_Enemy.GetName();
		m_MainOutput << ss.str();
		m_IsInitialized = true;
	}

	if(!m_IsThrown && SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		m_MainOutput.str("");

		m_IsThrown = true;
		m_EnemySprite->SetVisible(false);

		m_PokeballSprite->SetVisible(true);
		m_PokeballSprite->SetAnimation(4, 4, m_PokeballSprite->GetX(), m_PokeballSprite->GetY(), 0, 128, 32, 32, false, true);
	}
	else if(m_IsThrown && !m_Caught && !m_PokeballSprite->IsVisible())
	{
		if(m_Again)
		{
			m_Again = false;
			m_PokeballSprite->SetAnimation(4, 4, m_PokeballSprite->GetX(), m_PokeballSprite->GetY(), 0, 128, 32, 32, false, true);
			m_PokeballSprite->SetVisible(true);
		}
		else
		{
			m_Caught = true;

			float HpRatio = (float)m_Enemy.GetCurrentHP() / m_Enemy.GetMaxHP();
			int catchRand = rand() % 101;

			if(HpRatio > 0.7)
				m_Success = catchRand <= 10;
			else if(HpRatio > 0.5)
				m_Success = catchRand <= 25;
			else if(HpRatio > 0.3)
				m_Success = catchRand <= 40;
			else
				m_Success = catchRand <= 85;
			
			if(m_Success)
			{
				m_MainOutput << "You caught " + m_Enemy.GetName();
				m_Player.AddPokemon(m_Enemy);
				m_CurrentPokemon = m_Player.GetFirstPokemon();
				m_PlayerHpBar->SetPokemon(m_CurrentPokemon);
				m_PokeballSprite->SetAnimation(1, 4, m_PokeballSprite->GetX(), m_PokeballSprite->GetY(), 0, 128, 32, 32, true, true);
				m_PokeballSprite->SetVisible(true);
			}
			else
			{
				m_MainOutput << m_Enemy.GetName() + " broke free";
				m_EnemySprite->SetVisible(true);
			}
		}
	}
	else if(m_Caught && m_MainOutput.str() != "" && SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RETURN))
	{
		m_MainOutput.str("");
		m_IsInitialized = false;
		m_PokeballSprite->SetVisible(false);
		m_CurrentPokemon->SetHasAttacked(true);

		if(m_Success)
			m_CurrentPhase = COMBAT_INITIATION;
		else
			m_CurrentPhase = ENEMY_STANDBY;
	}
}

void CombatScene::DisplayAttackInfo()
{
	int currentPP;
	int maxPP;
	string type;

	if(m_ChoiceMatrix[0][0])
	{
		currentPP = m_CurrentPokemon->GetAttackAt(0).GetCurrentPP();
		maxPP = m_CurrentPokemon->GetAttackAt(0).GetAttackData().pp;
		type = GetStringFromType(m_CurrentPokemon->GetAttackAt(0).GetAttackData().type);
	}
	else if(m_ChoiceMatrix[0][1])
	{
		currentPP = m_CurrentPokemon->GetAttackAt(1).GetCurrentPP();
		maxPP = m_CurrentPokemon->GetAttackAt(1).GetAttackData().pp;
		type = GetStringFromType(m_CurrentPokemon->GetAttackAt(1).GetAttackData().type);
	}
	else if(m_ChoiceMatrix[1][0])
	{
		currentPP = m_CurrentPokemon->GetAttackAt(2).GetCurrentPP();
		maxPP = m_CurrentPokemon->GetAttackAt(2).GetAttackData().pp;
		type = GetStringFromType(m_CurrentPokemon->GetAttackAt(2).GetAttackData().type);
	}
	else
	{
		currentPP = m_CurrentPokemon->GetAttackAt(3).GetCurrentPP();
		maxPP = m_CurrentPokemon->GetAttackAt(3).GetAttackData().pp;
		type = GetStringFromType(m_CurrentPokemon->GetAttackAt(3).GetAttackData().type);
	}

	stringstream ss;
	ss << "PP " << currentPP << " / " << maxPP;
	*(m_AttackInfoMenu.GetTexts()[0]) = ss.str();

	*(m_AttackInfoMenu.GetTexts()[2]) = "   " + type;
}

void CombatScene::DisplayPokemonAttacks()
{
	vector<PokemonAttack> attacks = m_CurrentPokemon->GetAttacks();
	vector<PokemonAttack>::iterator iter = attacks.begin();
	int count = 0;

	while(count < MAX_POKEMON_ATTACK && iter != attacks.end())
	{
		*(m_AttackMenu.GetTexts()[count]) = attacks[count].GetAttackData().name;
		
		count++; iter++;
	}
}

void CombatScene::CheckCursorMovement(int _offsetX, int _offsetY)
{
	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RIGHT))
	{
		if(m_ChoiceMatrix[0][0])
		{
			m_ChoiceMatrix[0][0] = false;
			m_ChoiceMatrix[0][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() + _offsetX, m_Cursor->GetY());
		}
		else if(m_ChoiceMatrix[1][0])
		{
			m_ChoiceMatrix[1][0] = false;
			m_ChoiceMatrix[1][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() + _offsetX, m_Cursor->GetY());
		}
	}
	else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_LEFT))
	{
		if(m_ChoiceMatrix[0][1])
		{
			m_ChoiceMatrix[0][1] = false;
			m_ChoiceMatrix[0][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() - _offsetX, m_Cursor->GetY());
		}
		else if(m_ChoiceMatrix[1][1])
		{
			m_ChoiceMatrix[1][1] = false;
			m_ChoiceMatrix[1][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() - _offsetX, m_Cursor->GetY());
		}
	}
	else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_DOWN))
	{
		if(m_ChoiceMatrix[0][0])
		{
			m_ChoiceMatrix[0][0] = false;
			m_ChoiceMatrix[1][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() + _offsetY);
		}
		else if(m_ChoiceMatrix[0][1])
		{
			m_ChoiceMatrix[0][1] = false;
			m_ChoiceMatrix[1][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() + _offsetY);
		}
	}
	else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_UP))
	{
		if(m_ChoiceMatrix[1][0])
		{
			m_ChoiceMatrix[1][0] = false;
			m_ChoiceMatrix[0][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() - _offsetY);
		}
		else if(m_ChoiceMatrix[1][1])
		{
			m_ChoiceMatrix[1][1] = false;
			m_ChoiceMatrix[0][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() - _offsetY);
		}
	}
}


void CombatScene::CheckCursorMovementAttack(int _offsetX, int _offsetY)
{
	if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_RIGHT))
	{
		if(m_ChoiceMatrix[0][0] && m_CurrentPokemon->GetAttacks().size() > 1)
		{
			m_ChoiceMatrix[0][0] = false;
			m_ChoiceMatrix[0][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() + _offsetX, m_Cursor->GetY());
		}
		else if(m_ChoiceMatrix[1][0] && m_CurrentPokemon->GetAttacks().size() > 3)
		{
			m_ChoiceMatrix[1][0] = false;
			m_ChoiceMatrix[1][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() + _offsetX, m_Cursor->GetY());
		}
	}
	else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_LEFT))
	{
		if(m_ChoiceMatrix[0][1])
		{
			m_ChoiceMatrix[0][1] = false;
			m_ChoiceMatrix[0][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() - _offsetX, m_Cursor->GetY());
		}
		else if(m_ChoiceMatrix[1][1])
		{
			m_ChoiceMatrix[1][1] = false;
			m_ChoiceMatrix[1][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX() - _offsetX, m_Cursor->GetY());
		}
	}
	else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_DOWN))
	{
		if(m_ChoiceMatrix[0][0]  && m_CurrentPokemon->GetAttacks().size() > 2)
		{
			m_ChoiceMatrix[0][0] = false;
			m_ChoiceMatrix[1][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() + _offsetY);
		}
		else if(m_ChoiceMatrix[0][1])
		{
			if(m_CurrentPokemon->GetAttacks().size() > 3)
			{
				m_ChoiceMatrix[0][1] = false;
				m_ChoiceMatrix[1][1] = true;

				m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() + _offsetY);
			}
			else if(m_CurrentPokemon->GetAttacks().size() > 2)
			{
				m_ChoiceMatrix[0][1] = false;
				m_ChoiceMatrix[1][0] = true;

				m_Cursor->SetPosition(m_Cursor->GetX() - _offsetX, m_Cursor->GetY() + _offsetY);
			}
		}
	}
	else if(SDLInput::GetInstance()->IsDown(SDLKey::SDLK_UP))
	{
		if(m_ChoiceMatrix[1][0])
		{
			m_ChoiceMatrix[1][0] = false;
			m_ChoiceMatrix[0][0] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() - _offsetY);
		}
		else if(m_ChoiceMatrix[1][1])
		{
			m_ChoiceMatrix[1][1] = false;
			m_ChoiceMatrix[0][1] = true;

			m_Cursor->SetPosition(m_Cursor->GetX(), m_Cursor->GetY() - _offsetY);
		}
	}
}

string CombatScene::GetStringFromType(PokemonType _type) const
{
	switch(_type)
	{
	case NORMAL:
		return "NORMAL";
		break;
	case FIGHTING:
		return "FIGHTING";
		break;
	case FLYING:
		return "FLYING";
		break;
	case POISON:
		return "POISON";
		break;
	case GROUND:
		return "GROUND";
		break;
	case ROCK:
		return "ROCK";
		break;
	case BUG:
		return "BUG";
		break;
	case GHOST:
		return "GHOST";
		break;
	case FIRE:
		return "FIRE";
		break;
	case WATER:
		return "WATER";
		break;
	case GRASS:
		return "GRASS";
		break;
	case ELECTRIC:
		return "ELECTRIC";
		break;
	case PSYCHIC:
		return "PSYCHIC";
		break;
	case ICE:
		return "ICE";
		break;
	case DRAGON:
		return "DRAGON";
		break;
	default:
		return "";
		break;
	}
}